package com.ahuan.interceptor;

import com.ahuan.domain.UserAction;
import com.ahuan.exception.InterceptorException;
import com.ahuan.mapper.UserActionMapper;
import com.ahuan.resp.Res;
import com.ahuan.utils.JsonUtil;
import com.ahuan.utils.JwtUtil;
import com.ahuan.utils.TimeUtil;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDate;
import java.util.Date;

/**
 * @author Ahuan
 * @date 2023/3/23 16:04
 * @description: 定义拦截器链
 */
@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            //认证
            return validation(request, response);
//                    return true;

        } catch (Exception e) {
            e.printStackTrace();
            throw new InterceptorException("token验证时发生异常");
        }

    }

    private boolean validation(HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("进入拦截器：preHandle");
        //测试异常
//        if(true){
//            int a = 1/0;
//        }

        // 非普通访问时，发来的预检请求
        // 判断请求是否为预检请求
        if ("OPTIONS".equals(request.getMethod())) {
            // 设置响应头，允许跨域请求
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE");
            response.setHeader("Access-Control-Allow-Headers", "Authorization,Content-Type");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setStatus(HttpServletResponse.SC_OK);
            return false; // 预检请求不包含业务数据，立即停止访问，不再继续处理请求
        }

        response.setCharacterEncoding("utf-8");

        //获取请求参数中的token
        String token1 = request.getParameter("token");

        // 获取请求头中Authorization的token
        String token2 = request.getHeader("Authorization");

        String token = token1 != null ? token1 : token2;


        if (token != null) {
            boolean result = JwtUtil.verifyToken(token);
            if (result) {
                DecodedJWT decodedJWT = JwtUtil.decodeToken(token);
                String userName = decodedJWT.getClaim("userName").asString();
                String userId = decodedJWT.getClaim("userId").asString();
                // 将用户信息存储到MDC中，便于后续日志记录使用
                MDC.put("userName", userName);
                MDC.put("userId", userId);
                log.info("Token验证通过，用户名：{}，用户ID：{}", userName, userId);
                // 用户行为记录方案：分区(简单)、分表（采用）、分库（没必要）
                return loginLog(userId,userName);
            }
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try {
            Res res = new Res(false, "认证失败，未通过拦截器", "", 401);
            String json = JsonUtil.toJson(res);
            response.getWriter().append(json);
            log.info("Token验证失败");
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(500);
            return false;
        }
        return false;
    }
    @Autowired
    private UserActionMapper userActionMapper;

    private boolean loginLog(String userIdm,String username){
        UserAction userAction = new UserAction();
        userAction.setUsername("userName");
        userAction.setStartTime(new Date(System.currentTimeMillis()));
        userAction.setTableName("user_action_" + TimeUtil.getTime());
        System.out.println("---------------" + userAction.getTableName());

        if (userActionMapper.insert(userAction) > 0) {
            log.info("用户行为记录成功");
            return true;

        } else {
            throw new RuntimeException("用户行为记录失败");
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}


